package com.sina.shop.config;

import com.lambdaworks.redis.RedisClient;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cache.CacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;

import java.util.HashSet;
import java.util.Set;

/**
 * redis 配置
 */
@Configuration
@ConditionalOnClass({RedisTemplate.class, LettuceConnectionFactory.class, RedisClient.class})
public class RedisAutoConfig implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    private Environment environment;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        environment = applicationContext.getEnvironment();
    }

    @Bean
    @Primary
    public RedisConnectionFactory lettuceConnectionFactory() {
        LettuceConnectionFactory factory = new LettuceConnectionFactory();
        factory.setHostName(environment.getRequiredProperty("spring.redis.host"));
        factory.setPort(environment.getRequiredProperty("spring.redis.port", Integer.class));
        String value;
        value = environment.getRequiredProperty("spring.redis.password");
        if (StringUtils.hasText(value)) {
            factory.setPassword(value);
        }
        factory.setDatabase(environment.getRequiredProperty("spring.redis.database", Integer.class));
        return factory;
    }

    @Bean
    public StringRedisTemplate stringRedisTemplate(
            @Qualifier("lettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
        return new StringRedisTemplate(redisConnectionFactory);
    }

    @Bean
    @Primary
    @Autowired
    public RedisTemplate<String, Object> redisTemplate(
            @Qualifier("lettuceConnectionFactory") RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        StringRedisSerializer keySerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(keySerializer);
        redisTemplate.setHashKeySerializer(keySerializer);

        JdkSerializationRedisSerializer valueSerializer = new JdkSerializationRedisSerializer();
        redisTemplate.setValueSerializer(valueSerializer);
        redisTemplate.setHashValueSerializer(valueSerializer);

        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }


    @Bean
    public StringRedisTemplate stringRedisTemplateAt9(@Qualifier("lettuceConnectionFactoryAt9") RedisConnectionFactory factory) {
        return new StringRedisTemplate(factory);
    }


    @Bean
    public RedisConnectionFactory lettuceConnectionFactoryAt9() {
        LettuceConnectionFactory factory = new LettuceConnectionFactory();
        factory.setHostName(environment.getRequiredProperty("spring.redis.host"));
        factory.setPort(environment.getRequiredProperty("spring.redis.port", Integer.class));
        String value;
        value = environment.getRequiredProperty("spring.redis.password");
        factory.setPassword(value);
        factory.setDatabase(9);
        return factory;
    }


    @Bean
    @Autowired
    @ConditionalOnMissingBean(value = CacheManager.class, name = "redisCacheManager")
    public CacheManager redisCacheManager(@Qualifier("redisTemplate") RedisOperations redisOperations) {
        // configure and return CacheManager instance
        RedisCacheManager cacheManager = new RedisCacheManager(redisOperations);
        Set<String> cacheNames = new HashSet<>(6);
        cacheNames.add("appSecret");
        cacheNames.add("fundAsset");
        cacheNames.add("sinaSecretKey");
        cacheManager.setCacheNames(cacheNames);
        cacheManager.setUsePrefix(true);
        return cacheManager;
    }


}
